﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO.Ports;
using System.IO;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Management;

namespace StuMana.UI
{
    public partial class Connect : Form
    {

      public  struct IP_MAC
        {
            public string ip;
            public string macAddress;
        }


        public delegate void AsyncCallback(IAsyncResult ar);
        public delegate void AddTolstDiscoveredDevices(object o);

        private UdpState GlobalUDP;

        public Services.COM connect;
        private Timer readTimer;
        Services.SL025M rfid_reader = new Services.SL025M();

        private int size;
        private byte[] serial_buff = new byte[40];
        public Connect()
        {
            InitializeComponent();
            Connect_initial();
        }
        public Panel getPanel(int x, int y)
        {
            p_Connect.Location = new Point(x, y);
            return p_Connect;
        }

        /// <summary>
        ///  UDP
        /// </summary>
        struct UdpState
        {
            public System.Net.IPEndPoint EP;
            public System.Net.Sockets.UdpClient UDPClient;
        }

        private void cmdDiscoverDevices_Click(object sender, EventArgs e)
        {
            try
            {
                // Clear the listbox of all current discovery responses
                listView1.Items.Clear();

                // Try to send the discovery request message
              //  byte[] DiscoverMsg = Encoding.ASCII.GetBytes("Discovery: Who is out there?");

                IP_MAC ip_mac;
                ip_mac = GetIp_Mac();

                

                byte[] DiscoverMsg = Encoding.ASCII.GetBytes( ip_mac.ip + ip_mac.macAddress +"Discovery: Who is out there?");

                GlobalUDP.UDPClient.Send(DiscoverMsg, DiscoverMsg.Length, new System.Net.IPEndPoint(System.Net.IPAddress.Parse("255.255.255.0"), 30303));
            }
            catch
            {
                MessageBox.Show("Unable to transmit discovery message.  Check network connectivity and ensure that no other instances of this program are running.", "Error", MessageBoxButtons.OK);
                return;
            }
        }

        public void AddDiscoveryEntry(object o)
        {
            //lstDiscoveredDevices.Items.Add(o);
            listView1.Items.Add(new ListViewItem(((string)(o)).Split('\n')));
            //MessageBox.Show((string)(o),"Warning");
        }

        public void ReceiveCallback(IAsyncResult ar)
        {
            UdpState MyUDP = (UdpState)ar.AsyncState;

            // Obtain the UDP message body and convert it to a string, with remote IP address attached as well
            string ReceiveString = Encoding.ASCII.GetString(MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP));
            ReceiveString = MyUDP.EP.Address.ToString() + "\n" + ReceiveString.Replace("\r\n", "\n");

            // Configure the UdpClient class to accept more messages, if they arrive
            MyUDP.UDPClient.BeginReceive(ReceiveCallback, MyUDP);

            // Write the received UDP message text to the listbox in a thread-safe manner
            //lstDiscoveredDevices.Invoke(new AddTolstDiscoveredDevices(AddDiscoveryEntry), ReceiveString);
            listView1.Invoke(new AddTolstDiscoveredDevices(AddDiscoveryEntry), ReceiveString);
        }

        private void listView1_ItemActivate(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://" + listView1.SelectedItems[0].Text);
        }

        /*--------------------------------------------------------------*/
        private void Connect_initial()
        {
            string[] s = SerialPort.GetPortNames();
            int i = 0;
            
            cbb_baudrate.Items.Clear();
            cbb_baudrate.Items.Add("1200");
            cbb_baudrate.Items.Add("2400");
            cbb_baudrate.Items.Add("4800");
            cbb_baudrate.Items.Add("9600");
            cbb_baudrate.Items.Add("19200");
            cbb_baudrate.Items.Add("38400");
            cbb_baudrate.Items.Add("57600");
            cbb_baudrate.Items.Add("115200");
            cbb_baudrate.Items.Add("230400");
            cbb_baudrate.SelectedIndex = 4;

            cbb_com.Items.Clear();
            foreach (string port in s)
            {
                cbb_com.Items.Add(s[i]);
                i++;
            }
            if (cbb_com.Items.Count != 0)
                cbb_com.SelectedIndex = 0;

            readTimer = new Timer();
            readTimer.Interval = 300;
            readTimer.Tick += new EventHandler(readTimer_Tick);

            connect = new Services.COM(cbb_com.SelectedItem.ToString(), int.Parse(cbb_baudrate.SelectedItem.ToString()));


            
        }

        // timer handler
        private void readTimer_Tick(object sender, EventArgs e)
        {
            rfid_reader.selectCard();
            size = connect.getArray(serial_buff);

            if (size == 5000)
            {
                readTimer.Enabled = false;
                lb_status.Text = "No signal";

            }
            else
            {
                lb_status.Text = "";
                for (int cnt = 0; cnt < size; cnt++)
                {
                    lb_status.Text += Convert.ToString(serial_buff[cnt], 16).PadLeft(2, '0').PadRight(3, ' ').ToUpper();
                }
            }
        }

        // connect COM
        private void bt_connect_Click(object sender, EventArgs e)
        {
            try
            {
                connect = new Services.COM(cbb_com.SelectedItem.ToString(), int.Parse(cbb_baudrate.SelectedItem.ToString()));
                rfid_reader.get_connect(connect);
                bt_connect.Enabled = false;
                bt_disconnect.Enabled = true;
               // readTimer.Enabled = true;
                ts_connect.Text = "COM: " + cbb_com.SelectedItem.ToString();
                
            }
            catch (Exception es)
            {
                ts_connect.Text = "COM Error: " + es.Message;
            }
        }

        // set status
        public string setStatus()
        {
            return ts_connect.Text;
        }
        private void bt_disconnect_Click(object sender, EventArgs e)
        {
            try
            {
                readTimer.Enabled = false;

                if (!bt_connect.Enabled)
                    connect.closeCOMPort();

                // button connect disable
                bt_connect.Enabled = true;

                //button disconnect
                bt_disconnect.Enabled = false;

                //status connect
                lb_status.Text = "None";
            }
            catch (Exception es)
            {
                MessageBox.Show(es.Message, "COM Error");
            }
        }

        private void cbb_com_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void Connect_Load(object sender, EventArgs e)
        {

        }


        private IP_MAC GetIp_Mac()
        {
            IP_MAC kq;
            kq.ip = "";
            kq.macAddress = "";
            


            IPHostEntry host;
            string localIP = "";
            host = Dns.GetHostEntry(Dns.GetHostName());


            foreach (IPAddress ipAdd in host.AddressList)
            {

                if (ipAdd.AddressFamily == AddressFamily.InterNetwork)
                {
                    localIP = ipAdd.ToString();

                }


            }
            

            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = mc.GetInstances();
            string MACAddress = "";
            foreach (ManagementObject mo in moc)
            {

                if (mo["MacAddress"] != null)
                {
                    if ((bool)mo["IPEnabled"] == true)
                    {
                        MACAddress = mo["MacAddress"].ToString();
                        
                    }
                }
            }
            kq.ip = localIP;
            kq.macAddress = MACAddress;

            return kq;
        }

    }
}
